import os
import uuid
from PyQt6.QtWidgets import (
    QMainWindow, QPushButton, QFileDialog, QComboBox, QVBoxLayout,
    QWidget, QLabel, QListWidget, QProgressBar, QHBoxLayout, QSizePolicy
)
from PyQt6.QtGui import QFont, QMovie
from PyQt6.QtCore import Qt, QTimer
from config import load_voices
from utils import split_text_by_length, detect_encoding
from tts_worker import convert_file_to_mp3
from player import play_mp3_file, cleanup_speed_mp3
import pygame
pygame.mixer.init()

class TTSPlayer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("文本播放工具")
        self.file_conversion_status = {}
        self.file_segments_info = {}
        self.playback_speed = 1.0
        self.total_chars = 0
        self.converted_chars = 0
        self.stop_flag = False
        self.file_path_map = {}  # 文件名到完整路径的映射
        self.last_open_dir = None  # 新增：记住上次打开目录
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("文本播放工具")
        self.setMinimumSize(700, 400)
        main_layout = QHBoxLayout()
        # 左侧：文件列表
        left_layout = QVBoxLayout()
        self.file_list_widget = QListWidget()
        self.file_list_widget.setStyleSheet("QListWidget { border: 1px solid #aaa; font-size: 15px; }")
        self.file_list_widget.itemDoubleClicked.connect(self.on_file_double_clicked)
        left_layout.addWidget(QLabel("TXT文件列表"))
        left_layout.addWidget(self.file_list_widget)
        self.add_btn = QPushButton("添加TXT文件")
        self.add_btn.setStyleSheet("font-size: 15px;")
        self.add_btn.clicked.connect(self.add_file)
        left_layout.addWidget(self.add_btn)
        left_layout.addStretch()
        main_layout.addLayout(left_layout, 2)

        # 右侧：信息与控制
        right_layout = QVBoxLayout()
        self.label = QLabel("请选择要播放的TXT文件")
        self.label.setFont(QFont("微软雅黑", 14))
        self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        right_layout.addWidget(self.label)

        # 语言选择
        lang_layout = QHBoxLayout()
        self.lang_voices = load_voices()
        self.lang_box = QComboBox()
        self.lang_box.addItems(self.lang_voices.keys())
        self.voice_box = QComboBox()
        self.update_voice_box(self.lang_box.currentText())
        self.lang_box.currentTextChanged.connect(self.update_voice_box)
        self.voice_box.currentTextChanged.connect(self.set_voice)
        lang_layout.addWidget(QLabel("语言选择:"))
        lang_layout.addWidget(self.lang_box)
        lang_layout.addWidget(self.voice_box)
        lang_layout.addStretch()
        right_layout.addLayout(lang_layout)


        # 语速设置
        rate_layout = QHBoxLayout()
        rate_layout.addWidget(QLabel("语速:"))
        self.rate_box = QComboBox()
        self.rate_box.addItems([str(x) for x in [0.85,0.9,1.0,1.1,1.2,1.3,1.4,1.5]])
        self.rate_box.setCurrentText("1.0")
        rate_layout.addWidget(self.rate_box)
        rate_layout.addStretch()
        right_layout.addLayout(rate_layout)

        right_layout.addStretch()
        main_layout.addLayout(right_layout, 4)


        # 播放按钮
        self.play_btn = QPushButton("播放/暂停")
        self.play_btn.setStyleSheet("font-size: 16px; padding: 8px;")
        self.play_btn.clicked.connect(self.toggle_play)
        self.play_btn.setEnabled(False)
        right_layout.addWidget(self.play_btn)

        # 删除mp3按钮
        self.delete_mp3_btn = QPushButton("删除当前mp3")
        self.delete_mp3_btn.setStyleSheet("font-size: 15px; background:#e57373;")
        self.delete_mp3_btn.clicked.connect(self.delete_current_mp3)
        self.delete_mp3_btn.setVisible(False)
        right_layout.addWidget(self.delete_mp3_btn)

        # 等待动画
        self.wait_label = QLabel()
        self.wait_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.wait_label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        self.wait_movie = QMovie("loading.gif")
        self.wait_label.setMovie(self.wait_movie)
        self.wait_label.setVisible(False)
        right_layout.addWidget(self.wait_label)

        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setStyleSheet("QProgressBar { height: 24px; font-size: 16px; }")
        right_layout.addWidget(self.progress_bar)

        # 进度信息
        self.progress_label = QLabel("可播放字数: 0 / 总字数: 0")
        self.progress_label.setFont(QFont("微软雅黑", 13))
        self.progress_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        right_layout.addWidget(self.progress_label)

        # 当前播放文本显示
        self.current_text_label = QLabel("当前播放内容：")
        self.current_text_label.setFont(QFont("微软雅黑", 12))
        self.current_text_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
        right_layout.addWidget(self.current_text_label)

        self.current_text_display = QLabel("")
        self.current_text_display.setWordWrap(True)
        self.current_text_display.setFont(QFont("微软雅黑", 13))
        self.current_text_display.setStyleSheet("background:#f5f5f5; border:1px solid #ddd; padding:8px;")
        self.current_text_display.setMinimumHeight(60)
        right_layout.addWidget(self.current_text_display)

        # 播放速度控制
        speed_layout = QHBoxLayout()
        self.speed_label = QLabel("播放速度: 1.0x")
        speed_layout.addWidget(self.speed_label)
        self.speed_down_btn = QPushButton("-")
        self.speed_down_btn.clicked.connect(self.decrease_speed)
        speed_layout.addWidget(self.speed_down_btn)
        self.speed_up_btn = QPushButton("+")
        self.speed_up_btn.clicked.connect(self.increase_speed)
        speed_layout.addWidget(self.speed_up_btn)
        self.speed_reset_btn = QPushButton("重置")
        self.speed_reset_btn.clicked.connect(self.reset_speed)
        speed_layout.addWidget(self.speed_reset_btn)
        speed_layout.addStretch()
        right_layout.addLayout(speed_layout)



        widget = QWidget()
        widget.setLayout(main_layout)
        self.setCentralWidget(widget)

        # 初始化voice
        self.set_voice(self.voice_box.currentText())

    def update_voice_box(self, lang):
        self.voice_box.clear()
        voices = self.lang_voices.get(lang, {})
        self.voice_box.addItems(voices.keys())

    def set_voice(self, voice_name):
        lang = self.lang_box.currentText()
        if voice_name and lang in self.lang_voices and voice_name in self.lang_voices[lang]:
            self.voice = self.lang_voices[lang][voice_name]

    def add_file(self):
        start_dir = self.last_open_dir or os.getcwd()
        fnames, _ = QFileDialog.getOpenFileNames(self, "选择TXT文件", start_dir, "Text Files (*.txt)")
        if fnames:
            self.last_open_dir = os.path.dirname(fnames[0])
        for fname in fnames:
            file_basename = os.path.basename(fname)
            if file_basename and file_basename not in [self.file_list_widget.item(i).text() for i in range(self.file_list_widget.count())]:
                self.file_list_widget.addItem(file_basename)
                self.file_path_map[file_basename] = fname  # 记录映射
        self.play_btn.setEnabled(False)

    def on_file_double_clicked(self, item):
        # 通过文件名查找完整路径
        file_basename = item.text()
        fname = self.file_path_map[file_basename]
        self.txt_path = fname
        out_mp3 = os.path.splitext(fname)[0] + ".mp3"
        if os.path.exists(out_mp3):
            self.file_conversion_status[fname] = 'done'
            with open(fname, "r", encoding=detect_encoding(fname)) as f:
                file_text = f.read()
            self.total_chars = len(file_text)
            self.converted_chars = self.total_chars
            self.update_progress(self.converted_chars, self.total_chars)
            self.file_segments_info[fname] = []
            self.label.setText(f"正在播放: {os.path.basename(self.txt_path)}")
            self.play_btn.setEnabled(True)
            self.start_play()
            return
        # 读取当前所选语言和声音
        lang = self.lang_box.currentText()
        voice_name = self.voice_box.currentText()
        voice = self.lang_voices[lang][voice_name]
        rate = float(self.rate_box.currentText())
        with open(fname, "r", encoding=detect_encoding(fname)) as f:
            file_text = f.read()
        if file_text.strip():
            self.file_conversion_status[fname] = 'converting'
            self.total_chars = len(file_text)
            self.converted_chars = 0
            from threading import Thread
            Thread(target=convert_file_to_mp3, args=(fname, file_text, voice, self, rate), daemon=True).start()
        else:
            self.file_conversion_status[fname] = 'empty'
            self.label.setText("文件内容为空，无法播放")
        self.play_btn.setEnabled(False)

    def start_play(self):
        from threading import Thread
        self.stop_flag = False
        # 播放时禁用速度按钮
        self.speed_up_btn.setEnabled(False)
        self.speed_down_btn.setEnabled(False)
        self.speed_reset_btn.setEnabled(False)
        Thread(target=self.play_segments_worker, daemon=True).start()

    def play_segments_worker(self):
        out_mp3 = os.path.splitext(self.txt_path)[0] + ".mp3"
        try:
            play_file = play_mp3_file(out_mp3, self.playback_speed)
            self.update_progress(self.converted_chars, self.total_chars)
            while True:
                from pygame import mixer
                if self.stop_flag or not mixer.music.get_busy():
                    mixer.music.stop()
                    break
                QTimer.singleShot(100, lambda: None)
            if play_file != out_mp3:
                try:
                    os.remove(play_file)
                except Exception:
                    pass
        except Exception as e:
            self.show_error(f"播放错误: {e}")
        self.show_current_segment("")
        self.update_progress(self.converted_chars, self.total_chars)
        # 播放结束后恢复速度按钮
        self.speed_up_btn.setEnabled(True)
        self.speed_down_btn.setEnabled(True)
        self.speed_reset_btn.setEnabled(True)

    def update_progress(self, converted_chars=0, total_chars=0):
        def update():
            if total_chars == 0:
                self.progress_label.setText("可播放字数: 0 / 总字数: 0")
                self.progress_bar.setValue(0)
            else:
                self.progress_label.setText(
                    f"可播放字数: {converted_chars} / 总字数: {total_chars}"
                )
                self.progress_bar.setValue(int(converted_chars / total_chars * 100))
        QTimer.singleShot(0, update)

    def show_waiting(self, waiting):
        def update():
            self.wait_label.setVisible(waiting)
            if waiting:
                self.wait_movie.start()
            else:
                self.wait_movie.stop()
        QTimer.singleShot(0, update)

    def show_error(self, msg):
        def update():
            self.label.setText(msg)
        QTimer.singleShot(0, update)

    def show_info(self, msg):
        def update():
            self.label.setText(msg)
        QTimer.singleShot(0, update)

    def show_current_segment(self, text):
        def update():
            self.current_text_display.setText(text)
        QTimer.singleShot(0, update)

    def toggle_play(self):
        from pygame import mixer
        if mixer.music.get_busy():
            if not hasattr(self, 'is_paused'):
                self.is_paused = False
            if self.is_paused:
                mixer.music.unpause()
                self.is_paused = False
                self.play_btn.setText("暂停")
            else:
                mixer.music.pause()
                self.is_paused = True
                self.play_btn.setText("继续")
        else:
            self.is_paused = False
            self.start_play()
            self.play_btn.setText("暂停")

    def increase_speed(self):
        self.playback_speed = min(self.playback_speed + 0.1, 2.0)
        self.speed_label.setText(f"播放速度: {self.playback_speed:.1f}x")

    def decrease_speed(self):
        self.playback_speed = max(self.playback_speed - 0.1, 0.5)
        self.speed_label.setText(f"播放速度: {self.playback_speed:.1f}x")

    def reset_speed(self):
        self.playback_speed = 1.0
        self.speed_label.setText("播放速度: 1.0x")

    def delete_current_mp3(self):
        if not hasattr(self, 'txt_path') or not self.txt_path:
            self.show_error("未选择文件，无法删除mp3")
            return
        mp3_path = os.path.splitext(self.txt_path)[0] + ".mp3"
        import pygame
        # 停止播放并释放文件
        try:
            pygame.mixer.music.stop()
        except Exception:
            pass
        if os.path.exists(mp3_path):
            try:
                os.remove(mp3_path)
                self.show_info(f"已删除: {os.path.basename(mp3_path)}")
                self.play_btn.setEnabled(False)
            except Exception as e:
                self.show_error(f"删除失败: {e}")
        else:
            self.show_info("mp3文件不存在，无需删除")
            self.play_btn.setEnabled(False)

    def closeEvent(self, event):
        self.stop_flag = True
        cleanup_speed_mp3()
        event.accept()
